﻿using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Threading;

using WebServer.HTDOCS;
using WebServer.Modules;

namespace WebServer
{
	/// <summary>
	/// EventArgs supplied for each seperate Core Message received
	/// </summary>
	public sealed class CoreMessageEventArgs : EventArgs
	{
		private bool _Handled;
		/// <summary>
		/// Gets or Sets the handled variable which is used to track if this message has been handled by another method
		/// </summary>
		public bool Handled { get { return _Handled; } set { _Handled = value; } }

		private CoreMessageAction _Action;
		/// <summary>
		/// Gets or Sets the action associated with the message type
		/// </summary>
		public CoreMessageAction Action { get { return _Action; } set { _Action = value; } }

		private string _String;
		/// <summary>
		/// Gets or Sets the base message string
		/// </summary>
		public string String { get { return _String; } set { _String = value; } }

		private object[] _Args;
		/// <summary>
		/// Gets or Sets the arguments used when compiling the base message string
		/// </summary>
		public object[] Args { get { return _Args; } set { _Args = value; } }

		/// <summary>
		/// Gets the compiled message string
		/// </summary>
		public string Message { get { return Compile(); } }

		/// <summary>
		/// Creates an instance of CoreMessageEventArgs
		/// </summary>
		/// <param name="action">The action associated with the message type</param>
		/// <param name="message">The base string message</param>
		public CoreMessageEventArgs(CoreMessageAction action, string message)
		{
			_Action = action;
			_String = message;
			_Args = new object[0];
		}

		/// <summary>
		/// Creates an instance of CoreMessageEventArgs
		/// </summary>
		/// <param name="action">The action associated with the message type</param>
		/// <param name="format">The base string message</param>
		/// <param name="args">The arguments to insert into the base string format</param>
		public CoreMessageEventArgs(CoreMessageAction action, string format, params object[] args)
		{
			_Action = action;
			_String = format;
			_Args = args;
		}

		/// <summary>
		/// Returns the compiled Message as a string
		/// </summary>
		/// <returns>Compiled string for this message</returns>
		public string Compile()
		{
			if (_Args != null && _Args.Length > 0)
				return String.Format(_String, _Args);

			return _String;
		}

		/// <summary>
		/// Returns the compiled Message as a string
		/// </summary>
		/// <returns>Compiled string for this message</returns>
		public override string ToString()
		{
			return Compile();
		}
	}

	/// <summary>
	/// EventArgs supplied for each seperate HttpRequest received
	/// </summary>
	public sealed class HTTPRequestEventArgs : EventArgs
	{
		private RequestStatus _Status;
		/// <summary>
		/// Gets the status of the current Request.
		/// </summary>
		public RequestStatus Status { get { return _Status; } }

		private HttpListenerContext _Context;
		/// <summary>
		/// Gets the current Context reference.
		/// </summary>
		public HttpListenerContext Context { get { return _Context; } }

		private string _Message;
		/// <summary>
		/// Gets the error associated with the current Request.
		/// </summary>
		public string Message { get { return _Message; } }

		private Client _Client;
		/// <summary>
		/// Gets the Client connection associated with the current Request.
		/// </summary>
		public Client Client { get { return _Client; } }

		public HTTPRequestEventArgs(HttpListenerContext ctx, Client client, RequestStatus status)
		{
			_Context = ctx;
			_Client = client;
			_Status = status;
			_Message = _Context.Request.UserAgent;

			//Core.WriteLine(ToString());
		}

		public override string ToString()
		{
			return _Message;
		}
	}

	/// <summary>
	/// EventArgs supplied for each seperate HttpRequest received that has failed
	/// </summary>
	public sealed class HTTPRequestFailEventArgs : EventArgs
	{
		private HttpListenerContext _Context;
		/// <summary>
		/// Gets the current HttpListenerContext reference
		/// </summary>
		public HttpListenerContext Context { get { return _Context; } }

		private string _Message;
		/// <summary>
		/// Gets the error associated with the current Request
		/// </summary>
		public string Message { get { return _Message; } }

		private Client _Client;
		/// <summary>
		/// Gets the Client connection associated with the current Request
		/// </summary>
		public Client Client { get { return _Client; } }

		private IWebObject _WebObject;
		/// <summary>
		/// Gets the WebObject associated with the current Request
		/// </summary>
		public IWebObject WebObject { get { return _WebObject; } }

		/// <summary>
		/// Creates an instance of HTTPRequestFailEventArgs
		/// </summary>
		/// <param name="request">The Request that invoked the HTTPRequestFailEventArgs</param>
		/// <param name="url">The Request URL</param>
		/// <param name="client">The source Client connection</param>
		/// <param name="webObj">The WebObject instance associated with the failed Request</param>
		/// <param name="error">The Error message associated with the failed Request</param>
		public HTTPRequestFailEventArgs(HttpListenerContext ctx, Client client, IWebObject webObj, string message)
		{
			_Context = ctx;
			_Client = client;
			_WebObject = webObj;
			_Message = message;

			//Core.WriteLine(ToString());
		}

		/// <summary>
		/// Gets the string-representation of this HTTPRequestEventArgs instance
		/// </summary>
		/// <returns>WebObjectName: Error</returns>
		public override string ToString()
		{
			return _Message;
		}
	}

	/// <summary>
	/// EventArgs supplied for each seperate HttpRequest received that has succeeded
	/// </summary>
	public sealed class HTTPRequestSuccessEventArgs : EventArgs
	{
		private HttpListenerContext _Context;
		/// <summary>
		/// Gets the current Request reference
		/// </summary>
		public HttpListenerContext Context { get { return _Context; } }

		private string _Message;
		/// <summary>
		/// Gets the error associated with the current Request
		/// </summary>
		public string Message { get { return _Message; } }

		private Client _Client;
		/// <summary>
		/// Gets the Client connection associated with the current Request
		/// </summary>
		public Client Client { get { return _Client; } }

		private IWebObject _WebObject;
		/// <summary>
		/// Gets the WebObject associated with the current Request
		/// </summary>
		public IWebObject WebObject { get { return _WebObject; } }

		/// <summary>
		/// Creates an instance of HTTPRequestSuccessEventArgs
		/// </summary>
		/// <param name="request">The Request that invoked the HTTPRequestSuccessEventArgs</param>
		/// <param name="url">The Request URL</param>
		/// <param name="client">The source Client connection</param>
		/// <param name="webObj">The WebObject instance associated with the successful Request</param>
		/// <param name="error">The Error message associated with the successful Request</param>
		public HTTPRequestSuccessEventArgs(HttpListenerContext ctx, Client client, IWebObject webObj, string message)
		{
			_Context = ctx;
			_Client = client;
			_WebObject = webObj;
			_Message = message;

			//Core.WriteLine(ToString());
		}

		/// <summary>
		/// Gets the string-representation of this HTTPRequestEventArgs instance
		/// </summary>
		/// <returns>WebObjectName: Error</returns>
		public override string ToString()
		{
			return _Message;
		}
	}

	/// <summary>
	/// EventArgs supplied for each seperate web-webObj that is retrieved
	/// </summary>
	public sealed class WebObjectRetrievedEventArgs : EventArgs
	{
		private string _Error;
		/// <summary>
		/// Gets the error associated with the current Request
		/// </summary>
		public string Error { get { return _Error; } }

		private Client _Client;
		/// <summary>
		/// Gets the Client connection associated with the current Request
		/// </summary>
		public Client Client { get { return _Client; } }

		private Uri _URL;
		/// <summary>
		/// Gets the URL associated with the current Request
		/// </summary>
		public Uri URL { get { return _URL; } }

		private IWebObject _WebObject;
		/// <summary>
		/// Gets the WebObject associated with the current Request
		/// </summary>
		public IWebObject WebObject { get { return _WebObject; } }

		private string _WebObjectName;
		/// <summary>
		/// Gets the Name of the WebObject associated with the current Request
		/// </summary>
		public string WebObjectName { get { return _WebObjectName; } }
		
		/// <summary>
		/// Creates an instance of WebObjectRetrievedEventArgs
		/// </summary>
		/// <param name="url">The Request URL</param>
		/// <param name="client">The source Client connection</param>
		/// <param name="webObj">The WebObject instance associated with the Request</param>
		/// <param name="error">The Error message associated with the Request</param>
		public WebObjectRetrievedEventArgs(Uri url, Client client, IWebObject webObj, string error)
		{
			_Error = error;
			_URL = url;
			_Client = client;
			_WebObject = webObj;
			_WebObjectName = url.Segments[url.Segments.Length - 1];

			if (_WebObject is ErrorPage)
				((ErrorPage)_WebObject).Error = _Error;

			//Core.WriteLine(ToString());
		}

		/// <summary>
		/// Gets the string-representation of this HTTPRequestEventArgs instance
		/// </summary>
		/// <returns>WebObjectName: Error</returns>
		public override string ToString()
		{
			return String.Format("{0}: {1}", _WebObjectName, _Error);
		}
	}

	/*
	/// <summary>
	/// Not yet implimented. EventArgs supplied for each Command Request
	/// </summary>
	public sealed class CMDEventArgs : EventArgs
	{
		private ICommand _CMD;
		public ICommand CMD { get { return _CMD; } }

		private IPage _WebObject;
		public IPage WebObject { get { return _WebObject; } }

		private string[] _Args;
		public string[] Args { get { return _Args; } }

		public CMDEventArgs(ICommand cmd, IPage webObj, string[] args)
		{
			_CMD = cmd;
			_WebObject = webObj;
			_Args = args;
		}
	}
	*/

	public sealed class CoreModuleStartedEventArgs : EventArgs
	{
		private string _Name;
		public string Name { get { return _Name; } }

		private Type _TypeOf;
		public Type TypeOf { get { return _TypeOf; } }

		private CoreModulePriority _Priority;
		public CoreModulePriority Priority { get { return _Priority; } }

		public CoreModuleStartedEventArgs(string name, Type type, CoreModulePriority priority)
		{
			_Name = name;
			_TypeOf = type;
			_Priority = priority;
		}
	}
}
